use super::super::parallel::simd::{vector_ema, vector_sma, vector_std};
use serde::{Deserialize, Serialize};

/// KDJ指标计算结果
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct KDJResult {
    pub k: Vec<f64>,
    pub d: Vec<f64>,
    pub j: Vec<f64>,
}

/// 计算KDJ指标
pub fn calculate_kdj(
    high: &[f64],
    low: &[f64],
    close: &[f64],
    n: usize,
    m1: usize,
    m2: usize,
) -> KDJResult {
    let len = close.len();
    let mut rsv = Vec::with_capacity(len);
    let mut k = Vec::with_capacity(len);
    let mut d = Vec::with_capacity(len);
    let mut j = Vec::with_capacity(len);
    
    // 计算RSV
    for i in n-1..len {
        let hn = high[i-n+1..=i].iter().fold(f64::NEG_INFINITY, |a, &b| a.max(b));
        let ln = low[i-n+1..=i].iter().fold(f64::INFINITY, |a, &b| a.min(b));
        let rsv_val = if hn == ln {
            50.0
        } else {
            (close[i] - ln) / (hn - ln) * 100.0
        };
        rsv.push(rsv_val);
    }
    
    // 计算K值
    let k_values = unsafe { vector_sma(&rsv, m1) };
    k.extend(k_values);
    
    // 计算D值
    let d_values = unsafe { vector_sma(&k, m2) };
    d.extend(d_values);
    
    // 计算J值
    for i in 0..k.len() {
        let j_val = 3.0 * k[i] - 2.0 * d[i];
        j.push(j_val);
    }
    
    KDJResult { k, d, j }
}

/// TRIX指标计算结果
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TRIXResult {
    pub trix: Vec<f64>,
    pub matrix: Vec<f64>,
}

/// 计算TRIX指标
pub fn calculate_trix(close: &[f64], n: usize) -> TRIXResult {
    // 计算三重指数平滑移动平均
    let ema1 = unsafe { vector_ema(close, 1.0 / n as f64) };
    let ema2 = unsafe { vector_ema(&ema1, 1.0 / n as f64) };
    let ema3 = unsafe { vector_ema(&ema2, 1.0 / n as f64) };
    
    let mut trix = Vec::with_capacity(close.len());
    let mut matrix = Vec::with_capacity(close.len());
    
    // 计算TRIX值
    for i in 1..ema3.len() {
        let trix_val = (ema3[i] - ema3[i-1]) / ema3[i-1] * 100.0;
        trix.push(trix_val);
    }
    
    // 计算MATRIX值（TRIX的移动平均）
    let matrix_values = unsafe { vector_sma(&trix, n) };
    matrix.extend(matrix_values);
    
    TRIXResult { trix, matrix }
}

/// DMA指标计算结果
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DMAResult {
    pub dma: Vec<f64>,
    pub ama: Vec<f64>,
}

/// 计算DMA指标
pub fn calculate_dma(close: &[f64], short_period: usize, long_period: usize, ama_period: usize) -> DMAResult {
    // 计算短期和长期移动平均
    let ma_short = unsafe { vector_sma(close, short_period) };
    let ma_long = unsafe { vector_sma(close, long_period) };
    
    let mut dma = Vec::with_capacity(close.len());
    
    // 计算DMA值
    for i in 0..ma_short.len().min(ma_long.len()) {
        let dma_val = ma_short[i] - ma_long[i];
        dma.push(dma_val);
    }
    
    // 计算AMA值
    let ama = unsafe { vector_sma(&dma, ama_period) };
    
    DMAResult { dma, ama }
}

/// EMV指标计算结果
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct EMVResult {
    pub emv: Vec<f64>,
    pub maemv: Vec<f64>,
}

/// 计算EMV指标
pub fn calculate_emv(high: &[f64], low: &[f64], volume: &[f64], n: usize) -> EMVResult {
    let len = high.len();
    let mut em = Vec::with_capacity(len);
    let mut emv = Vec::with_capacity(len);
    
    // 计算中间价和成交量的变化
    for i in 1..len {
        let mid = (high[i] + low[i]) / 2.0;
        let last_mid = (high[i-1] + low[i-1]) / 2.0;
        let vol_div = volume[i] / 100000.0;
        
        let distance = high[i] - low[i];
        if distance != 0.0 {
            let em_val = (mid - last_mid) * distance / vol_div;
            em.push(em_val);
        } else {
            em.push(0.0);
        }
    }
    
    // 计算EMV值
    let emv_values = unsafe { vector_sma(&em, n) };
    emv.extend(emv_values);
    
    // 计算MAEMV值
    let maemv = unsafe { vector_sma(&emv, n) };
    
    EMVResult { emv, maemv }
}

/// ASI指标计算结果
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ASIResult {
    pub asi: Vec<f64>,
    pub asit: Vec<f64>,
}

/// 计算ASI指标
pub fn calculate_asi(open: &[f64], high: &[f64], low: &[f64], close: &[f64], n: usize) -> ASIResult {
    let len = close.len();
    let mut si = Vec::with_capacity(len);
    let mut asi = Vec::with_capacity(len);
    
    for i in 1..len {
        let a = (high[i] - close[i-1]).abs();
        let b = (low[i] - close[i-1]).abs();
        let c = (high[i] - low[i-1]).abs();
        let d = (close[i-1] - open[i-1]).abs();
        
        let k = a.max(b);
        let m = if a >= b && a >= c { a + b/2.0 + d/4.0 }
               else if b >= a && b >= c { b + a/2.0 + d/4.0 }
               else { c + d/4.0 };
        
        let r = if m == 0.0 { 0.0 } else {
            16.0 * ((close[i] - close[i-1] + (close[i] - open[i])/2.0 + (close[i-1] - open[i-1])/2.0) * k / m)
        };
        
        si.push(r);
    }
    
    // 计算ASI值
    let mut sum = 0.0;
    for &s in &si {
        sum += s;
        asi.push(sum);
    }
    
    // 计算ASIT值
    let asit = unsafe { vector_sma(&asi, n) };
    
    ASIResult { asi, asit }
}

/// PSY指标计算结果
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PSYResult {
    pub psy: Vec<f64>,
    pub psyma: Vec<f64>,
}

/// 计算PSY指标
pub fn calculate_psy(close: &[f64], n: usize, m: usize) -> PSYResult {
    let len = close.len();
    let mut psy = Vec::with_capacity(len);
    
    for i in n..len {
        let mut up_count = 0;
        for j in i-n+1..=i {
            if close[j] > close[j-1] {
                up_count += 1;
            }
        }
        let psy_val = (up_count as f64 / n as f64) * 100.0;
        psy.push(psy_val);
    }
    
    // 计算PSYMA值
    let psyma = unsafe { vector_sma(&psy, m) };
    
    PSYResult { psy, psyma }
}

/// VR指标计算结果
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct VRResult {
    pub vr: Vec<f64>,
    pub mavr: Vec<f64>,
}

/// 计算VR指标
pub fn calculate_vr(close: &[f64], volume: &[f64], n: usize) -> VRResult {
    let len = close.len();
    let mut vr = Vec::with_capacity(len);
    
    for i in n..len {
        let mut avs = 0.0;
        let mut bvs = 0.0;
        let mut cvs = 0.0;
        
        for j in i-n+1..=i {
            if close[j] > close[j-1] {
                avs += volume[j];
            } else if close[j] < close[j-1] {
                bvs += volume[j];
            } else {
                cvs += volume[j];
            }
        }
        
        let vr_val = if bvs == 0.0 {
            100.0
        } else {
            (avs + cvs/2.0) / (bvs + cvs/2.0) * 100.0
        };
        vr.push(vr_val);
    }
    
    // 计算MAVR值
    let mavr = unsafe { vector_sma(&vr, n) };
    
    VRResult { vr, mavr }
}

/// CR指标计算结果
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CRResult {
    pub cr: Vec<f64>,
    pub ma1: Vec<f64>,
    pub ma2: Vec<f64>,
    pub ma3: Vec<f64>,
    pub ma4: Vec<f64>,
}

/// 计算CR指标
pub fn calculate_cr(high: &[f64], low: &[f64], n: usize, m1: usize, m2: usize, m3: usize, m4: usize) -> CRResult {
    let len = high.len();
    let mut cr = Vec::with_capacity(len);
    
    for i in 1..len {
        let mid = (high[i-1] + low[i-1]) / 2.0;
        let p1 = (high[i] - mid).max(0.0);
        let p2 = (mid - low[i]).max(0.0);
        
        let cr_val = if p2 == 0.0 {
            100.0
        } else {
            p1 / p2 * 100.0
        };
        cr.push(cr_val);
    }
    
    // 计算不同周期的移动平均
    let ma1 = unsafe { vector_sma(&cr, m1) };
    let ma2 = unsafe { vector_sma(&cr, m2) };
    let ma3 = unsafe { vector_sma(&cr, m3) };
    let ma4 = unsafe { vector_sma(&cr, m4) };
    
    CRResult { cr, ma1, ma2, ma3, ma4 }
}

/// CCI指标计算结果
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CCIResult {
    pub cci: Vec<f64>,
}

/// 计算CCI指标
pub fn calculate_cci(high: &[f64], low: &[f64], close: &[f64], n: usize) -> CCIResult {
    let len = close.len();
    let mut tp = Vec::with_capacity(len);
    let mut cci = Vec::with_capacity(len);
    
    // 计算典型价格
    for i in 0..len {
        let tp_val = (high[i] + low[i] + close[i]) / 3.0;
        tp.push(tp_val);
    }
    
    // 计算移动平均和标准差
    let ma = unsafe { vector_sma(&tp, n) };
    let std_dev = unsafe { vector_std(&tp[n-1..]) };
    
    // 计算CCI值
    for i in 0..ma.len() {
        let cci_val = if std_dev[i] != 0.0 {
            (tp[i+n-1] - ma[i]) / (0.015 * std_dev[i])
        } else {
            0.0
        };
        cci.push(cci_val);
    }
    
    CCIResult { cci }
}

/// ARBR指标计算结果
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ARBRResult {
    pub ar: Vec<f64>,
    pub br: Vec<f64>,
}

/// 计算ARBR指标
pub fn calculate_arbr(open: &[f64], high: &[f64], low: &[f64], close: &[f64], n: usize) -> ARBRResult {
    let len = close.len();
    let mut ar = Vec::with_capacity(len);
    let mut br = Vec::with_capacity(len);
    
    for i in n..len {
        let mut ar_h = 0.0;
        let mut ar_l = 0.0;
        let mut br_h = 0.0;
        let mut br_l = 0.0;
        
        for j in i-n+1..=i {
            ar_h += high[j] - open[j];
            ar_l += open[j] - low[j];
            br_h += high[j] - close[j-1];
            br_l += close[j-1] - low[j];
        }
        
        let ar_val = if ar_l == 0.0 { 100.0 } else { ar_h / ar_l * 100.0 };
        let br_val = if br_l == 0.0 { 100.0 } else { br_h / br_l * 100.0 };
        
        ar.push(ar_val);
        br.push(br_val);
    }
    
    ARBRResult { ar, br }
}

/// DPO指标计算结果
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DPOResult {
    pub dpo: Vec<f64>,
    pub madpo: Vec<f64>,
}

/// 计算DPO指标
pub fn calculate_dpo(close: &[f64], n: usize, m: usize) -> DPOResult {
    let len = close.len();
    let mut dpo = Vec::with_capacity(len);
    
    // 计算移动平均
    let ma = unsafe { vector_sma(close, n) };
    
    // 计算DPO值
    for i in n-1..len {
        let x = (n as f64 / 2.0 + 1.0).floor() as usize;
        if i >= x {
            let dpo_val = close[i] - ma[i-x];
            dpo.push(dpo_val);
        }
    }
    
    // 计算MADPO值
    let madpo = unsafe { vector_sma(&dpo, m) };
    
    DPOResult { dpo, madpo }
}

/// BIAS指标计算结果
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct BIASResult {
    pub bias1: Vec<f64>,
    pub bias2: Vec<f64>,
    pub bias3: Vec<f64>,
}

/// 计算BIAS指标
pub fn calculate_bias(close: &[f64], n1: usize, n2: usize, n3: usize) -> BIASResult {
    let len = close.len();
    let mut bias1 = Vec::with_capacity(len);
    let mut bias2 = Vec::with_capacity(len);
    let mut bias3 = Vec::with_capacity(len);
    
    // 计算不同周期的移动平均
    let ma1 = unsafe { vector_sma(close, n1) };
    let ma2 = unsafe { vector_sma(close, n2) };
    let ma3 = unsafe { vector_sma(close, n3) };
    
    // 计算BIAS值
    for i in 0..ma1.len() {
        let bias1_val = (close[i+n1-1] - ma1[i]) / ma1[i] * 100.0;
        bias1.push(bias1_val);
    }
    
    for i in 0..ma2.len() {
        let bias2_val = (close[i+n2-1] - ma2[i]) / ma2[i] * 100.0;
        bias2.push(bias2_val);
    }
    
    for i in 0..ma3.len() {
        let bias3_val = (close[i+n3-1] - ma3[i]) / ma3[i] * 100.0;
        bias3.push(bias3_val);
    }
    
    BIASResult { bias1, bias2, bias3 }
}

#[cfg(test)]
mod tests {
    use super::*;
    
    #[test]
    fn test_kdj() {
        let high = vec![10.0, 12.0, 11.0, 13.0, 14.0];
        let low = vec![8.0, 9.0, 8.0, 10.0, 11.0];
        let close = vec![9.0, 10.0, 9.0, 12.0, 13.0];
        
        let result = calculate_kdj(&high, &low, &close, 3, 2, 2);
        assert!(!result.k.is_empty());
        assert!(!result.d.is_empty());
        assert!(!result.j.is_empty());
    }
    
    #[test]
    fn test_trix() {
        let close = vec![10.0, 11.0, 12.0, 11.0, 13.0];
        let result = calculate_trix(&close, 3);
        assert!(!result.trix.is_empty());
        assert!(!result.matrix.is_empty());
    }
    
    #[test]
    fn test_dma() {
        let close = vec![10.0, 11.0, 12.0, 11.0, 13.0];
        let result = calculate_dma(&close, 2, 3, 2);
        assert!(!result.dma.is_empty());
        assert!(!result.ama.is_empty());
    }
}